<template>
  <el-dialog
    :title="title"
    :visible.sync="visible"
    :close-on-click-modal="false"
    :show-close="false"
    width="700px"
  >
    <el-input
      placeholder="搜索"
      size="small"
      clearable
      prefix-icon="el-icon-search"
      v-model="filterText"
      @input="search"
    >
    </el-input>
    <div class="user-breadcrumb">
      <span
        v-for="(item, index) in breadcrumb"
        :key="index"
        @click="handle(item)"
        >{{ item.name }}
        <i class="el-icon-arrow-right" v-if="breadcrumb.length != index + 1"></i
      ></span>
    </div>
    <div class="user-panel">
      <div class="user-panel-left">
        <div class="user-panel-left-checkAll">
          <el-checkbox v-model="isAll" @change="checkedAll">全选</el-checkbox>
        </div>
        <div class="user-panel-left-node">
          <div
            class="user-panel-left-node-item"
            v-for="(item, index) in newData"
            :key="new Date().getTime() + index"
          >
            <div class="user-panel-left-node-item-name">
              <el-checkbox
                :checked="isChecked(item)"
                @change="(val) => checkNode(val, item)"
              >
                <i
                  class="el-icon-folder"
                  v-if="item[defaultProps.id] == defaultProps.defaultParentId"
                ></i>
                <i
                  class="el-icon-user"
                  v-if="item[defaultProps.id] != defaultProps.defaultParentId"
                ></i>
                {{ item[defaultProps.name] }}
              </el-checkbox>
            </div>
            <div
              class="user-panel-left-node-item-handle"
              v-if="item[defaultProps.id] == defaultProps.defaultParentId"
            >
              <el-link
                :underline="false"
                :disabled="isCheckedDept(item) || filterText != ''"
                icon="el-icon-guide"
                @click="nextLevel(item)"
                >下级</el-link
              >
            </div>
          </div>
          <el-empty
            description="暂无数据"
            v-if="newData.length == 0"
          ></el-empty>
        </div>
      </div>
      <div class="user-panel-right">
        <el-table :data="checkAll">
          <el-table-column label="姓名">
            <template slot-scope="scope">
              {{ scope.row[defaultProps.name] }}
            </template>
          </el-table-column>
          <el-table-column align="center" width="50px">
            <template slot="header">
              <el-link :underline="false" type="danger" @click="removeAll"
                >清空</el-link
              >
            </template>
            <template slot-scope="scope">
              <el-link
                type="danger"
                :underline="false"
                @click="remove(scope.row)"
                ><i class="el-icon-delete"></i
              ></el-link>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
    <div slot="footer" class="dialog-footer">
      <span class="wrap-btn wrap-success" @click="save">确定</span>
      <span class="wrap-btn wrap-default" @click="close">取消</span>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: 'userPanelPlus',
  props: {
    visible: {
      type: Boolean,
      default: () => {
        return false
      },
    },
    title: {
      type: String,
      default: () => {
        return '选择人员'
      },
    },
    data: {
      type: Array,
      default: () => {
        return []
      },
    },
    check: {
      type: Array,
      default: () => {
        return []
      },
    },
    defaultProps: {
      type: Object,
      default: () => {
        return {
          key: 'id',
          defaultParentId: '0',
          parentId: 'parentId',
          id: 'userId',
          name: 'name',
          children: 'children',
        }
      },
    },
  },
  data() {
    return {
      filterText: '',
      breadcrumb: [],
      isAll: false,
      newData: [],
      checkAll: [],
    }
  },
  watch: {
    visible() {
      let list = this.mapTree(this.data)
      this.filterText = ''
      this.breadcrumb = []
      this.checkAll = []
      this.check.forEach((element) => {
        if (element.id == '') {
          const arr = list.filter(
            (item) =>
              item[this.defaultProps.id] == element[this.defaultProps.id]
          )
          this.checkAll = this.deWeight(
            this.checkAll.concat(arr),
            this.defaultProps.id
          )
        } else {
          const arr = list.filter(
            (item) =>
              item[this.defaultProps.key] == element[this.defaultProps.key]
          )
          this.checkAll = this.deWeight(
            this.checkAll.concat(arr),
            this.defaultProps.key
          )
        }
      })
      this.nextLevel()
    },
  },
  methods: {
    search(val) {
      //搜索
      let arr = this.breadcrumb[this.breadcrumb.length - 1].item
      let list = this.mapTree(arr)
      if (val) {
        const arr = list.filter((item) =>
          item[this.defaultProps.name].includes(val)
        )
        //拼音检索
        const enArr = list.filter((item) => item.enName.includes(val))
        this.newData = this.userAndDept(arr.concat(enArr))
      } else {
        this.newData = arr
      }
    },
    nextLevel(item) {
      //下一级
      this.breadcrumb.push({
        name: item ? item[this.defaultProps.name] : '通讯录',
        item: item ? item[this.defaultProps.children] : [...this.data],
      })
      this.newData = item ? item[this.defaultProps.children] : [...this.data]
      this.isCheckAll()
    },
    handle(item) {
      //导航
      const index = this.breadcrumb.indexOf(item) + 1
      const breadcrumb = this.breadcrumb.slice(0, index)
      this.breadcrumb = breadcrumb
      this.newData = item.item
      this.isAll = false
    },
    checkedAll(val) {
      //全选
      if (val) {
        this.checkAll = this.deWeight(
          this.checkAll.concat(this.newData),
          this.defaultProps.key
        )
      } else {
        this.checkAll = [...this.checkAll].filter((x) =>
          [...this.newData].every(
            (y) => y[this.defaultProps.key] !== x[this.defaultProps.key]
          )
        )
      }
    },
    checkNode(val, item) {
      //选中
      if (val) {
        this.checkAll = this.checkAll.concat(item)
      } else {
        const index = this.checkAll.indexOf(item)
        if (index !== -1) {
          this.checkAll.splice(index, 1)
        }
      }
      this.isCheckAll()
    },
    isChecked(item) {
      //默认选中人
      if (item[this.defaultProps.id] == this.defaultProps.defaultParentId) {
        return this.checkAll.some(
          (el) => el[this.defaultProps.key] == item[this.defaultProps.key]
        )
      } else {
        return this.checkAll.some(
          (el) => el[this.defaultProps.id] == item[this.defaultProps.id]
        )
      }
    },
    isCheckedDept(item) {
      //默认选中部门
      return this.checkAll.some(
        (el) => el[this.defaultProps.key] == item[this.defaultProps.key]
      )
    },
    removeAll() {
      //清空
      this.checkAll = []
      this.isCheckAll()
    },
    remove(item) {
      //删除
      const index = this.checkAll.indexOf(item)
      if (index !== -1) {
        this.checkAll.splice(index, 1)
        this.isCheckAll()
      }
    },
    mapTree(data) {
      //将树结构展平成数组对象
      let arr = []
      for (let i = 0, l = data.length; i < l; i++) {
        arr.push(data[i])
        if (
          data[i][this.defaultProps.children] &&
          data[i][this.defaultProps.children].length > 0
        ) {
          arr = arr.concat(this.mapTree(data[i][this.defaultProps.children]))
        }
      }
      return arr
    },
    isCheckAll() {
      //判断是否满足全选条件
      const len = this.newData.length
      let checkLen = 0
      this.checkAll.forEach((element) => {
        const index = this.newData.indexOf(element)
        if (index !== -1) {
          checkLen += 1
        }
      })
      if (len == checkLen) {
        this.isAll = true
      } else {
        this.isAll = false
      }
    },
    close() {
      this.$emit('close')
    },
    save() {
      //保存
      let list = this.mapTree(this.checkAll)
      if (this.checkAll.length == 0) {
        this.$message.error('请' + this.title)
        return
      } else {
        let arr = []
        list.forEach((element) => {
          arr.push({
            [this.defaultProps.key]: element[this.defaultProps.key],
            [this.defaultProps.id]: element[this.defaultProps.id],
            [this.defaultProps.name]: element[this.defaultProps.name],
          })
        })
        this.$emit('save', this.userAndDept(arr))
      }
    },
    userAndDept(data) {
      let map = new Map()
      for (let item of data) {
        if (item[this.defaultProps.id] == this.defaultProps.defaultParentId) {
          if (!map.has(item[this.defaultProps.key])) {
            map.set(item[this.defaultProps.key], item)
          }
        } else if (!map.has(item[this.defaultProps.id])) {
          map.set(item[this.defaultProps.id], item)
        }
      }
      return [...map.values()]
    },
    deWeight(arrayObject, attribute) {
      //对象数组去重
      let map = new Map()
      for (let item of arrayObject) {
        if (!map.has(item[attribute])) {
          map.set(item[attribute], item)
        }
      }
      return [...map.values()]
    },
  },
}
</script>
<style lang="scss" scoped>
.user-breadcrumb {
  padding: 10px 0;
  span:not(:last-child) {
    color: #409eff;
    cursor: pointer;
    i {
      color: #c0c4cc;
      margin: 0 5px;
    }
  }
}
.user-panel {
  width: 100%;
  height: 302px;
  display: flex;
  > div {
    border: 1px solid #e4e7ed;
    height: 300px;
    overflow-y: scroll;
  }
  > div::-webkit-scrollbar {
    width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
    height: 1px;
  }
  > div::-webkit-scrollbar-thumb {
    border-radius: 5px;
    background-color: #2d82f6;
    background-image: -webkit-linear-gradient(
      45deg,
      rgba(255, 255, 255, 0.2) 25%,
      transparent 25%,
      transparent 50%,
      rgba(255, 255, 255, 0.2) 50%,
      rgba(255, 255, 255, 0.2) 75%,
      transparent 75%,
      transparent
    );
  }
  > div::-webkit-scrollbar-track {
    border-radius: 5px;
  }
  &-left {
    width: 340px;
    &-checkAll {
      padding: 5px 10px;
      margin-left: 5px;
    }
    &-node {
      &-item {
        margin-left: 5px;
        padding: 5px 0 5px 10px;
        cursor: pointer;
        overflow: hidden;
        &-name {
          display: inline-block;
          width: 255px;
          ::v-deep.el-checkbox {
            width: 100%;
            overflow: hidden;
            .el-checkbox__input {
              vertical-align: bottom;
            }
            .el-checkbox__label {
              width: calc(100% - 30px);
              white-space: nowrap;
              text-overflow: ellipsis;
              overflow: hidden;
              font-size: 14px;
              vertical-align: middle;
            }
          }
          i {
            color: #409eff;
          }
        }
        &-handle {
          display: inline-block;
          width: 50px;
          border-left: 1px solid #e4e7ed;
          vertical-align: inherit;
          font-size: 14px;
          line-height: 19px;
          text-align: right;
          padding-right: 10px;
          cursor: pointer;
          ::v-deep.el-link {
            color: #c0c4cc;
            .el-link--inner {
              margin: 0;
            }
          }
          ::v-deep.el-link:hover {
            color: #409eff;
          }
        }
      }
      &-item:hover {
        background: #f2f6fc;
      }
    }
  }
  &-right {
    flex: 1;
    margin-left: 20px;
  }
}
</style>
